package com.weishao.dbmapper.engine.impl;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.sql.DataSource;
import org.apache.logging.log4j.util.Strings;
import com.weishao.common.database.DatabaseOperatorFactory;
import com.weishao.common.database.IDatabaseOperator;
import com.weishao.dbmapper.IResultRowHandler;
import com.weishao.dbmapper.engine.AbstractMapperService;
import com.weishao.dbmapper.engine.IMapperService;
import com.weishao.dbmapper.pojo.TaskParamEntity;

/**
 * 一对一映射转换类
 * 
 * @author tang
 *
 */
public class OneByOneMapperImpl extends AbstractMapperService implements IMapperService {

	public OneByOneMapperImpl(DataSource dataSource, int fetchSize, boolean quiet) {
		super(dataSource, fetchSize, quiet);
	}

	@Override
	public void mapper(TaskParamEntity task, IResultRowHandler handler) {
		/**
		 * <p>
		 * 因存在源表的一个字段被映射为目的表的多个字段的情况
		 * </p>
		 * <p>
		 * 所以这里的map中, key存储的为映射的目的表字段名称，value存储的为映射的源表字段名称。
		 * </p>
		 */
		List<String> sourceColumns = new ArrayList<String>();
		List<String> targetColumns = new ArrayList<String>();
		Map<String, Set<Integer>> orderMap = new HashMap<String, Set<Integer>>();
		int i = 0;
		for (Map.Entry<String, String> entry : task.getFieldsMapper().entrySet()) {
			if (!sourceColumns.contains(entry.getValue())) {
				sourceColumns.add(entry.getValue());
			}

			targetColumns.add(entry.getKey());

			if (null == orderMap.get(entry.getValue())) {
				orderMap.put(entry.getValue(), new HashSet<Integer>());
			}
			orderMap.get(entry.getValue()).add(i);

			i++;
		}

		// 对于一对一映射来说，如果从应用层传入了查询的SQL，则优先使用应用层的查询SQL
		String querySql = task.getViewSql();
		if (Strings.isEmpty(querySql)) {
			DataSource ds = this.jdbcTemplate.getDataSource();
			IDatabaseOperator operator = DatabaseOperatorFactory.createDatabaseOperator(ds);
			querySql= operator.getSelectTableSql(task.getSchemaName(), task.getTableName(), sourceColumns);
		}

		this.doDataTransfer(querySql, handler, targetColumns, orderMap, task.getValuesMapper());
	}
}